package com.qen.encrypt.utils;

import cn.hutool.extra.spring.SpringUtil;
import com.qen.encrypt.http.DecryptMultipartRequestWrapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 从Request直接取附件的工具类
 *
 * @author licz
 * @data 2025年08月04日 11:09
 */
public class DecryptUtils {


    /**
     * 从Request取指定类型
     *
     * @param request
     * @param targetClass
     * @param <T>
     * @return
     */
    public static <T> T findWrapper(HttpServletRequest request, Class<T> targetClass) {
        HttpServletRequest current = request;
        while (current != null) {
            if (targetClass.isInstance(current)) {
                return targetClass.cast(current);
            }
            if (current instanceof HttpServletRequestWrapper) {
                current = (HttpServletRequest) ((HttpServletRequestWrapper) current).getRequest();
            } else {
                break;
            }
        }
        return null;
    }

    /**
     * 从Request取指定DecryptMultipartRequestWrapper类型
     *
     * @param request
     * @return
     */
    public static DecryptMultipartRequestWrapper findWrapper(HttpServletRequest request) {
        return findWrapper(request, DecryptMultipartRequestWrapper.class);
    }

    /**
     * 取所有附件
     *
     * @param request
     * @return
     */
    public static MultiValueMap<String, MultipartFile> getMultiValue(HttpServletRequest request) {
        if (!isMultipart(request)) {
            return null;
        }
        List<Class> classes = getAllRequest(request);
        if (classes.contains(DecryptMultipartRequestWrapper.class)) {
            return findWrapper(request).getMultiFileMap();
        } else {
            MultipartResolver multipartResolver = SpringUtil.getBean(MultipartResolver.class);
            MultipartHttpServletRequest multipartHttpServletRequest = multipartResolver.resolveMultipart(request);
            return multipartHttpServletRequest.getMultiFileMap();
        }
    }

    /**
     * 取指定附件
     *
     * @param request
     * @param name
     * @return
     */
    public static MultipartFile getMultiValue(HttpServletRequest request, String name) {
        if (!isMultipart(request)) {
            return null;
        }
        List<Class> classes = getAllRequest(request);
        if (classes.contains(DecryptMultipartRequestWrapper.class)) {
            return findWrapper(request).getFile(name);
        } else {
            MultipartResolver multipartResolver = SpringUtil.getBean(MultipartResolver.class);
            MultipartHttpServletRequest multipartHttpServletRequest = multipartResolver.resolveMultipart(request);
            return multipartHttpServletRequest.getFile(name);
        }
    }

    /**
     * 取指定附件
     *
     * @param request
     * @param name
     * @return
     */
    public static List<MultipartFile> getMultiValues(HttpServletRequest request, String name) {
        if (!isMultipart(request)) {
            return null;
        }
        List<Class> classes = getAllRequest(request);
        if (classes.contains(DecryptMultipartRequestWrapper.class)) {
            return findWrapper(request).getFiles(name);
        } else {
            MultipartResolver multipartResolver = SpringUtil.getBean(MultipartResolver.class);
            MultipartHttpServletRequest multipartHttpServletRequest = multipartResolver.resolveMultipart(request);
            return multipartHttpServletRequest.getFiles(name);
        }
    }

    /**
     * 判断请求是否是带附件的,借鉴commons-fileupload-1.4.jar
     *
     * @param request
     * @return
     */
    public static boolean isMultipart(HttpServletRequest request) {
        if (!"POST".equalsIgnoreCase(request.getMethod())) {
            return false;
        }
        var ctx = new ServletRequestContext(request);
        String contentType = ctx.getContentType();
        if (contentType == null) {
            return false;
        } else {
            return contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/");
        }
    }

    /**
     * 获取Request的所有类型
     *
     * @param request
     * @return
     */
    public static List<Class> getAllRequest(HttpServletRequest request) {
        HttpServletRequest current = request;
        List<Class> classes = new ArrayList<>();
        do {
            if (current instanceof HttpServletRequestWrapper) {
                current = (HttpServletRequest) ((HttpServletRequestWrapper) current).getRequest();
                classes.add(current.getClass());
            } else {
                break;
            }
        } while (current != null);
        return classes;
    }


}
